/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.rukopisy.tools.cli.imageLinks;

import cz.mzk.kramerius.commons.Dom4jUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.XPath;

/**
 *
 * @author Martin Řehánek <rehan at mzk.cz>
 */
public class PagePidUrlSuffixMapper {

    private static final Logger logger = Logger.getLogger(PagePidUrlSuffixMapper.class.getName());
    private final XPath logPagesPath = Dom4jUtils.createXPath("//pages");
    private final XPath logPidXpath = Dom4jUtils.createXPath("pid");
    private final XPath logLabelXpath = Dom4jUtils.createXPath("label");
    private final XPath teiFacsimilePath = Dom4jUtils.createXPath("//tei:facsimile");
    private final XPath teiLabelXpath = Dom4jUtils.createXPath("tei:desc/tei:label");
    private final XPath urlSuffixXpath = Dom4jUtils.createXPath("tei:graphic[1]/@url");
    private final Map<String, String> pidSuffixMap = new HashMap<String, String>();

    public PagePidUrlSuffixMapper(Document importLog, Document tei) throws Exception {
        List<Element> logPages = getLogPageElements(importLog);
        List<Element> teiSurfaces = getTeiSurfaceElements(tei);
        initUuidLinkMap(logPages, teiSurfaces);
    }

    private List<Element> getLogPageElements(Document importLog) {
        Element pages = (Element) logPagesPath.selectSingleNode(importLog);
        List<Node> logPages = pages.content();
        return keepOnlyNamedElements(logPages, "model_page");
    }

    private List<Element> getTeiSurfaceElements(Document tei) {
        Element facsimile = (Element) teiFacsimilePath.selectSingleNode(tei);
        List<Node> teiSurfaces = facsimile.content();
        return keepOnlyNamedElements(teiSurfaces, "surface");
    }

    private List<Element> keepOnlyNamedElements(List<Node> original, String elementName) {
        List<Element> result = new ArrayList<Element>();
        for (Node node : original) {
            if (node instanceof Element && elementName.equals(node.getName())) {
                result.add((Element) node);
            }
        }
        return result;
    }

    private void initUuidLinkMap(List<Element> logPages, List<Element> teiSurfaces) throws Exception {
        if (logPages.size() != teiSurfaces.size()) {
            throw new Exception("number of pages in import log(" + logPages.size() + ") differs from number of pages in tei(" + teiSurfaces.size());
        }
        logger.log(Level.INFO, "initializing mapping");
        for (int i = 0; i < logPages.size(); i++) {
            addMapping(logPages.get(i), teiSurfaces.get(i));
            //TODO:remove break
            //break;
        }
    }

    private void addMapping(Element logPage, Element teiSurface) throws Exception {
        String pagePid = findNodeContent(logPage, logPidXpath);
        logger.log(Level.INFO, "page pid: {0}", pagePid);
        String teiLabel = findNodeContent(teiSurface, teiLabelXpath);
        logger.log(Level.INFO, "page label(tei): {0}", teiLabel);
        String logLabel = findNodeContent(logPage, logLabelXpath);
        logger.log(Level.INFO, "page label(log): {0}", logLabel);
        if (!teiLabel.equals(logLabel)) {
            throw new Exception("label for page in tei differs from label in import log");
        }
        String urlSuffix = parseUrlSuffix(findNodeContent(teiSurface, urlSuffixXpath));
        logger.log(Level.INFO, "url suffix: {0}", urlSuffix);
        pidSuffixMap.put(pagePid, urlSuffix);
    }

    private String findNodeContent(Element rootEl, XPath xpath) throws Exception {
        Node node = xpath.selectSingleNode(rootEl);
        if (node == null) {
            throw new Exception("cannot find '" + xpath.toString() + "'");
        }
        return node.getText();
    }

    private String parseUrlSuffix(String text) {
        String[] tokens = text.split("/");
        String imageFile = tokens[tokens.length - 1];
        return imageFile.substring(0, imageFile.length() - ".jpg".length());
    }

    public String getUrlSuffix(String pagePid) {
        return pidSuffixMap.get(pagePid);
    }
}
